/**
* ComplexButton class "wraps" an IComplexButton type and adds typical event handlers
* @author Devon O.
*/

package src.uipackage.ui.complexbuttons {
	
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import com.onebyonedesign.ui.complexbuttons.events.ComplexButtonEvent;

	public class ComplexButton extends Sprite {
		
		private var _mouseDown:Boolean = false;
		private var _buttonPressed:Boolean = false;
		private var _selected:Boolean = false;
		
		private var _buttonInstance:*;
		
		/**
		* 
		* @param	IComplexButton button type
		* @param	specifies whether or not to use hand cursor for buttons
		*/
		public function ComplexButton(btn:IComplexButton, showHand:Boolean) {
			if (btn.data == null) throw new Error("ComplexButton Error: button must have data property.");
			
			_buttonInstance = btn;
			_buttonInstance.mouseChildren = false;
			_buttonInstance.buttonMode = true;
			_buttonInstance.useHandCursor = showHand;
				
			_buttonInstance.addEventListener(Event.ADDED_TO_STAGE, init);
			_buttonInstance.addEventListener(Event.REMOVED_FROM_STAGE, kill);
			addChild(_buttonInstance);
		}
		
		public function get buttonInstance():* {
			return _buttonInstance;
		}
		
		private function init(event:Event = null):void {
			_buttonInstance.removeEventListener(Event.ADDED_TO_STAGE, init);
			
			_buttonInstance.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
			_buttonInstance.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
			_buttonInstance.addEventListener(MouseEvent.ROLL_OVER, onMouseOver);
			_buttonInstance.addEventListener(MouseEvent.ROLL_OUT, onMouseOut);
		}
		
		private function onMouseDown(event:MouseEvent):void {
			if (event.currentTarget == _buttonInstance) {
				_buttonPressed = true;
				onPress();
			}
			_mouseDown = true;
			_buttonInstance.stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
		}
		
		private function onMouseUp(event:MouseEvent):void {
			if (event.currentTarget == _buttonInstance) {
				if (_buttonPressed) onRelease();
			} else if (_buttonPressed) {
				onReleaseOutside();
			}
			_buttonInstance.stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
			_buttonPressed = false;
			_mouseDown = false;
		}
		
		private function onMouseOver(event:MouseEvent):void {
			if (_mouseDown) {
				onDragOver();
			} else {
				onRollOver();
			}
		}
		
		private function onMouseOut(event:MouseEvent):void {
			if (_mouseDown) {
				onDragOut();
			} else {
				onRollOut();
			}
			if (_buttonPressed) _buttonPressed = false;
		}
		
		//	standard button actions
		
		private function onPress():void {
			// may want this line in some instances, out in others.
			//_buttonInstance.displayDown();
			dispatch(ComplexButtonEvent.PRESS);
		}
		private function onRelease():void {
			_buttonInstance.mouseEnabled = false;
			_buttonInstance.displayDown();
			dispatch(ComplexButtonEvent.RELEASE);
			_selected = true;
		}
		private function onReleaseOutside():void {
			dispatch(ComplexButtonEvent.RELEASE_OUTSIDE);
		}
		private function onRollOver():void {
			_buttonInstance.displayOver();
			dispatch(ComplexButtonEvent.ROLL_OVER);
		}
		private function onRollOut():void {
			if (!_selected) {
				_buttonInstance.displayUp();
				dispatch(ComplexButtonEvent.ROLL_OUT);
			}
		}
		private function onDragOver():void {
			_buttonInstance.displayOver();
			dispatch(ComplexButtonEvent.DRAG_OVER);
		}
		private function onDragOut():void {
			_buttonInstance.displayUp();
			dispatch(ComplexButtonEvent.DRAG_OUT);
		}
		
		private function dispatch(type:String):void {
			dispatchEvent(new ComplexButtonEvent(type, _buttonInstance.data));
		}
		
		internal function reset():void {
			_selected = false;
			_buttonInstance.displayUp();
			_buttonInstance.mouseEnabled = true;
		}
		
		private function kill(event:Event):void {
			_buttonInstance.removeEventListener(Event.REMOVED_FROM_STAGE, kill);
			
			_buttonInstance.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
			_buttonInstance.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
			_buttonInstance.removeEventListener(MouseEvent.ROLL_OVER, onMouseOver);
			_buttonInstance.removeEventListener(MouseEvent.ROLL_OUT, onMouseOut);
		}
		
		internal function get data():String {
			return _buttonInstance.data;
		}
		internal function get selected():Boolean {
			return _selected;
		}
		internal function set selected(sel:Boolean):void {
			_selected = sel;
			_buttonInstance.displayDown();
			_buttonInstance.mouseEnabled = false;
		}
	}
}
